package org.file5.controller;

import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.Logger;
import org.file5.domain.Article;
import org.file5.domain.BaseEntity;
import org.file5.domain.Category;
import org.file5.domain.EntityComment;
import org.file5.search.SearchResult;
import org.file5.search.SearchUtility;
import org.file5.service.CategoryService;
import org.file5.service.ServiceFascade;
import org.file5.util.DataBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

import com.google.appengine.api.users.UserService;

@Controller
public class ArticleController {
	private final Logger logger = Logger.getLogger(this.getClass());

	@Autowired
	private ServiceFascade sf;
	@Autowired
	private UserService googleUserService;

	@RequestMapping(value = "/articles", method = RequestMethod.GET)
	public String listArticles(@RequestParam(value = "pageNo", required = false) Integer pageNo, Model model) {
		return listArticlesBy(CategoryService.TOP_SITE_ARTICLE_CATEGORY_UID, pageNo, DataBean.PAGE_SIZE_PUBLIC, model);
	}

	@RequestMapping(value = "/articles/{categoryUid}", method = RequestMethod.GET)
	public String listArticlesBy(@PathVariable("categoryUid") String categoryUid,
			@RequestParam(value = "pageNo", required = false) Integer pageNo,
			@RequestParam(value = "pageSize", required = false) Integer pageSize, Model model) {

		if (pageNo == null || pageNo < 0) {
			pageNo = 0;
		}
		if (pageSize == null || pageSize < 1) {
			pageSize = DataBean.PAGE_SIZE_PUBLIC;
		}
		Category g = sf.getCategoryService().find(categoryUid);
		DataBean<Article> dataBean = sf.getArticleService().getArticles(pageNo * pageSize, pageSize, g,
				BaseEntity.STATUS.ONLINE);

		model.addAttribute("pageNo", pageNo);
		model.addAttribute("pageSize", pageSize);
		if (dataBean != null && !dataBean.isEmpty()) {
			model.addAttribute("articles", dataBean.getData());
			model.addAttribute("totalItems", dataBean.getCount());
		}

		if (g != null) {
			model.addAttribute("currentCategory", g);
			model.addAttribute("primaryCategoryTrail", g.getPrimaryCategoryTrail());
			model.addAttribute("childCategories", g.getChildCategories());

		}
		model.addAttribute("categoryUid", categoryUid);

		return "articles";
	}

	@RequestMapping(value = "/articles/tag/{tag}", method = RequestMethod.GET)
	public String listArticlesByTag(@PathVariable("tag") String tag,
			@RequestParam(value = "pageNo", required = false) Integer pageNo,
			@RequestParam(value = "pageSize", required = false) Integer pageSize, Model model) {

		if (pageNo == null || pageNo < 0) {
			pageNo = 0;
		}
		if (pageSize == null || pageSize < 1) {
			pageSize = DataBean.PAGE_SIZE_PUBLIC;
		}
		SearchResult searchResult = SearchUtility.search(tag, Article.class, null, pageNo * pageSize, (pageNo + 1)
				* pageSize);
		if (searchResult != null && searchResult.getData() != null) {
			List<Article> similarArticles = this.convertToArticleList(searchResult);
			model.addAttribute("articles", similarArticles);
			model.addAttribute("totalItems", searchResult.getTotalCount());
		}
		model.addAttribute("tag", tag);

		return "articlestag";
	}

	@RequestMapping(value = "/article/{uid}", method = RequestMethod.GET)
	public String viewArticle(@PathVariable("uid") String uid, Model model) {

		Article article = sf.getArticleService().find(uid, true);
		if (article != null) {
			if (article.getPrimaryCategoryKey() != null) {
				List<Category> primaryCategoryTrail = sf.getCategoryService().getPrimaryCategoryTrail(
						article.getPrimaryCategoryKey());
				model.addAttribute("primaryCategoryTrail", primaryCategoryTrail);
				model.addAttribute("currentCategory", article.getPrimaryCategory());
			}
			model.addAttribute("article", article);

			if (article.getTags() != null && !article.getTags().isEmpty()) {
				String[] tags = article.getTags().split(",; ");
				if (tags.length > 0) {
					String keyword = tags[0];
					SearchResult searchResult = SearchUtility.search(keyword, Article.class, null, 0, 10);
					List<Article> similarArticles = this.convertToArticleList(searchResult);
					model.addAttribute("similarArticles", similarArticles);
				}
			}

			if (article.getGroupTag() != null && !article.getGroupTag().isEmpty()) {
				DataBean<Article> db = sf.getArticleService().getArticlesByProperties(0, 100, "groupTag",
						article.getGroupTag());
				if (db.getData() != null && !db.getData().isEmpty()) {
					model.addAttribute("sameGroupArticles", db.getData());
				}
			}

			DataBean<EntityComment> dbc = sf.getArticleService().getArticleComments(0, 100, uid, null);
			if (dbc.getData() != null && !dbc.getData().isEmpty()) {
				model.addAttribute("articleComments", dbc.getData());
			}
		}
		model.addAttribute("uid", uid);
		String personUid = sf.getPersonService().getPersonUid(googleUserService.getCurrentUser());
		model.addAttribute("code", personUid);

		return "article";
	}

	/**
	 * Converts the search result to list of ideas.
	 * 
	 * @param searchResultOfArticleAndComment
	 * @return
	 */
	private List<Article> convertToArticleList(SearchResult searchResult) {
		List<Article> ideas = new ArrayList<Article>();
		if (searchResult != null && searchResult.getData() != null) {
			Article idea = null;
			for (Object obj : searchResult.getData()) {
				if (obj instanceof Article) {
					idea = (Article) obj;
					Article a = sf.getArticleService().find(idea.getUid(), true);
					if (a != null) {
						ideas.add(a);
					} else {
						SearchUtility.deleteEntityIndex(idea);// no used
																// indexEntity
					}
				}
			}
		}
		return ideas;
	}

}
